/*
 * @Copyright: 2017 www.yyfax.com Inc. All rights reserved.
 */
package com.yyfax.pay.order.service;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yyfax.framework.exception.YYException;
import com.yyfax.framework.yyfax.enums.YesNoEnum;
import com.yyfax.pay.common.enums.PayModeEnum;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.enums.PayTypeEnum;
import com.yyfax.pay.common.enums.PaymentEnum;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.config.data.service.MerchantPaymentService;
import com.yyfax.pay.config.data.service.PaymentRouteService;
import com.yyfax.pay.config.model.po.MerchantPaymentPO;
import com.yyfax.pay.config.model.po.PaymentRoutePO;

/**
 * 路由服务,提供各种接口的路由
 * 
 * @author jiangmy
 * @date 2017-04-11 10:14:43
 * @since v1.0.0
 */
@Service
public class RouteService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private MerchantPaymentService merchantPaymentService;

	@Autowired
	private PaymentRouteService paymentRouteService; // 商户银行支付路由信息

	/**
	 * 卡Bin接口路由
	 * 
	 * @author jiangmy
	 * @date 2017-04-11 10:21:17
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Exception
	 */
	public PaymentEnum routeCardBin(String merchantCode, String cardNo) throws Exception {
		MerchantPaymentPO merchantPaymentPO = merchantPaymentService.queryDefaultByMerchantCode(merchantCode, PayTypeEnum.CARD_BIN.getValue(),
				PayModeEnum.AUTH_PAY.getValue(), null);

		if (merchantPaymentPO == null) {
			throw new YYException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT, "卡bin路由失败，没有找到相关配置", "卡bin路由失败，没有找到相关配置");
		}

		return PaymentEnum.fromValue(merchantPaymentPO.getPaymentCode());
	}

	/**
	 * 代付路由
	 * 
	 * @author jiangmy
	 * @date 2017-04-11 10:21:30
	 * @since v1.0.0
	 * @param req
	 * @return
	 */
	public PaymentEnum routePayout(String merchantCode, String cardNo) throws YYPayException {
		return null;
	}

	/**
	 * 支付路由<br>
	 * 
	 * <pre>
	 * 优先查询银行支付路由表，如果没有命中，则继续查询商户支付通道默认配置。
	 * 如果有传偏好支付通道，则查询商户支付通道配置；
	 * </pre>
	 * 
	 * @author jiangmy
	 * @date 2017-04-11 10:21:43
	 * @since v1.0.0
	 * @param merchantCode 商户编号
	 * @param bankCode 银行编号
	 * @param prefPaymentCode 偏好支付通道
	 * @param payMode 支付模式
	 * @param apiType 支付接口模式
	 * @return
	 * @throws Exception
	 */
	public PaymentEnum routePay(String merchantCode, String bankCode, String prefPaymentCode, String payMode, String apiType) throws Exception {
		if (StringUtils.isNotBlank(prefPaymentCode)) { // 如果传偏好支付通道，则查询商户支付通道配置是否存在
			MerchantPaymentPO merchantPaymentPO = merchantPaymentService.queryByThirdMerchantCode(merchantCode, prefPaymentCode,
					PayTypeEnum.PAY.getValue(), payMode);
			if (merchantPaymentPO == null) {
				throw new YYPayException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT);
			}

			// 如果商户有相关支付通道配置则,返回支付渠道为偏好设置
			return PaymentEnum.fromValue(prefPaymentCode);
		}

		// 如果没有传偏好支付渠道，则查询银行支付路由
		if (StringUtils.isNotBlank(bankCode)) {
			PaymentRoutePO paymentRoutePO = paymentRouteService.queryByBankCode(merchantCode, bankCode);
			//支付路由信息必须是有效的
			if (paymentRoutePO != null && YesNoEnum.YES.isValue(paymentRoutePO.getState())) {
				MerchantPaymentPO merchPO = merchantPaymentService.queryByThirdMerchantCode(paymentRoutePO.getMerchantCode(),
						paymentRoutePO.getPaymentCode(), PayTypeEnum.PAY.getValue(), payMode);
				if (StringUtils.isNotBlank(apiType)) { // 如果支付接口类型有值，则判断当前支付通道知否满足条件
					if (merchPO != null && StringUtils.equals(merchPO.getApiType(), apiType)) {
						return PaymentEnum.fromValue(paymentRoutePO.getPaymentCode());
					}
				}

				if (merchPO != null) { //如果指定模式不存在
					return PaymentEnum.fromValue(paymentRoutePO.getPaymentCode());
				}
			}
		}

		// 如果没有银行支付路由配置，则查询商户支付通道默认配置
		MerchantPaymentPO merchantPaymentPO = merchantPaymentService.queryDefaultByMerchantCode(merchantCode, PayTypeEnum.PAY.getValue(), payMode,
				apiType);
		if (merchantPaymentPO == null) {
			throw new YYPayException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT,
					"商户:" + merchantCode + "不支持改支付类型，payMode:" + payMode + ",apiType:" + apiType, "无效请求");
		}

		return PaymentEnum.fromValue(merchantPaymentPO.getPaymentCode());
	}

	/**
	 * 路由支付通道<br>
	 * 如果有传偏好支付通道编号，则验证商户支付通道关系，关系存在，且合法值返回支付通道枚举值；
	 * 如果没有传偏好支付通道编号，则查询银行路由，如果存在银行路由信息，则返回相应支付通道枚举，如果不存在银行路由信息，则查询商户支付通道关系默认值；
	 * 
	 * @author buyi
	 * @date 2017-04-15 18:07:31
	 * @since v1.0.0
	 * @param merchantCode
	 * @param prefPaymentCode
	 * @param bankCode
	 * @param payType
	 * @param payMode
	 * @return
	 * @throws Exception 支付通道信息配置异常
	 * @throws YYPayException
	 *         支付通道编号非法时，抛出异常{@link PayRspCodeEnum.PAY_CODE_ILLEGAL_PAYMENT_CODE}。商户不支持时，则抛出异常{@link PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT}
	 */
	// private PaymentEnum route(String merchantCode, String prefPaymentCode, String bankCode, String payType, String payMode) throws Exception {
	// if (StringUtils.isNotBlank(prefPaymentCode)) { // 如果传偏好支付通道，则查询商户支付通道配置是否存在
	// MerchantPaymentPO merchantPaymentPO = merchantPaymentService.queryByThirdMerchantCode(merchantCode, prefPaymentCode, payType, payMode);
	// if (merchantPaymentPO == null) {
	// throw new YYException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT);
	// }
	//
	// // 如果商户有相关支付通道配置则,返回支付渠道为偏好设置
	// PaymentEnum paymentEnum = PaymentEnum.fromValue(prefPaymentCode);
	//
	// if (paymentEnum == null) {
	// throw new YYException(PayRspCodeEnum.PAY_CODE_ILLEGAL_PAYMENT_CODE);
	// }
	//
	// return paymentEnum;
	// }
	//
	// // 如果没有传偏好支付渠道，则查询银行支付路由
	// if (StringUtils.isNotBlank(bankCode)) {
	// PaymentRoutePO paymentRoutePO = paymentRouteService.queryByBankCode(merchantCode, bankCode);
	// if (paymentRoutePO != null) {
	// return PaymentEnum.fromValue(paymentRoutePO.getPaymentCode());
	// }
	// }
	//
	// // 如果没有银行支付路由配置，则查询商户支付通道默认配置
	// MerchantPaymentPO merchantPaymentPO = merchantPaymentService.queryDefaultByMerchantCode(merchantCode, payType, payMode);
	// if (merchantPaymentPO == null) {
	// throw new YYPayException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT);
	// }
	//
	// PaymentEnum paymentEnum = PaymentEnum.fromValue(merchantPaymentPO.getPaymentCode());
	//
	// if (paymentEnum == null) { // 支付通道非法
	// throw new YYException(PayRspCodeEnum.PAY_CODE_ILLEGAL_PAYMENT_CODE);
	// }
	//
	// return paymentEnum;
	// }

	/**
	 * 独立鉴权路由
	 * 
	 * @author jiangmy
	 * @date 2017-04-11 10:21:50
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Exception
	 */
	public PaymentEnum routeAuthentication(String merchantCode, String prefPaymentCode) throws Exception {
		MerchantPaymentPO merchantPaymentPO = null;
		if (StringUtils.isNotBlank(prefPaymentCode)) { // 如果存在偏好支付通道
			merchantPaymentPO = merchantPaymentService.queryByThirdMerchantCode(merchantCode, prefPaymentCode, PayTypeEnum.AUTH.getValue(),
					PayModeEnum.AUTH_PAY.getValue());
		} else { // 如果不存在偏好支付通道，则查询独立鉴权默认支付通道
			merchantPaymentPO = merchantPaymentService.queryDefaultByMerchantCode(merchantCode, PayTypeEnum.AUTH.getValue(),
					PayModeEnum.AUTH_PAY.getValue(), null);
		}

		if (merchantPaymentPO == null || !YesNoEnum.YES.isValue(merchantPaymentPO.getState())) {
			throw new YYException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_SUPPORT_PAYMENT, "缺失有效的[独立鉴权]类型配置");
		}

		PaymentEnum paymentEnum = PaymentEnum.fromValue(merchantPaymentPO.getPaymentCode());
		if (paymentEnum == null) {
			logger.error("存在非法的支付通道配置，merchant_payment,merchantCode:" + merchantCode + ",paymentCode:" + merchantPaymentPO.getPaymentCode());
			throw new YYException(PayRspCodeEnum.PAY_CODE_ILLEGAL_PAYMENT_CODE);
		}

		return paymentEnum;

	}

}
